<script setup lang="ts">
// 需安装 pinyin-match
// 导入子组件 SubMenu - 可下拉的菜单
// import SubMenu from './S-subMenu.vue'
// 导入自定义的数据类型
import PinYinMatch from "pinyin-match";
interface menu {
  id?: number | string;
  label: string;
  path: string;
  menuHide?: boolean;
  nickName?: string;
  icon?: string;
  index?: string;
  children?: menu[];
}
interface MenuProps {
  menu_list: menu[];
  default_openeds?: string[];
  collapse?: boolean;
  homePage?: string;
}
/** 父组件传参
 * @param menu_list 菜单列表
 * @param default_openeds 默认展开的菜单索引列表
 * @param collapse 是否展开菜单
 */
const { menu_list, default_openeds, collapse } = defineProps<MenuProps>();
// 菜单数据是否完成初始化
let menuInitOK = ref(false);
// 搜索菜单的关键字
let keyWords = ref("");
// 过滤后的菜单列表
let filtered_menu_list = ref<menu[]>([]);
// 菜单的层级数
let deep = getTreeDeep(menu_list);
// 当前展开的菜单层级
let currentPage = ref(deep);
// 初始化后的菜单列表
const new_menu_list = init_menu_list(menu_list);
// 所有菜单节点列表
let menuNodesList: menu[] = [];
// 生成所有菜单节点列表
getAllTreeNode(new_menu_list, menuNodesList);
// 获取当前路由
const route = useRoute();
// 高亮的菜单索引
let activeMenuIndex = ref("");
// 监听当前路由的路径变化，获取高亮的菜单索引
watch(
  () => route.path,
  (newPath) => {
    activeMenuIndex.value = "";
    menuNodesList.forEach((item) => {
      if (newPath === item.path) {
        activeMenuIndex.value = item.index || "";
      }
    });
  },
  { immediate: true }
);
/**
 * 更改展开菜单的层级
 * @param val 要更改到的层级
 */
const openeds_change = async (val: number) => {
  if (val) {
    currentPage.value = val;
  }
  openeds.value = [];
  menuNodesList.forEach((item) => {
    if (item.index && item.index.split("-").length < currentPage.value) {
      openeds.value.push(item.index);
    }
  });
  menuInitOK.value = false;
  await nextTick();
  menuInitOK.value = true;
};
// 展开的菜单索引列表
let openeds = ref<string[]>([]);
// 若配置了默认展开的菜单索引列表，则采用该列表，若未配置，则展开全部菜单
if (!default_openeds) {
  openeds_change(deep);
} else {
  openeds.value = default_openeds;
  menuInitOK.value = true;
}
// 事件input -- 输入菜单搜索关键字
const keyWords_change = async (newKeyWords: string) => {
  filtered_menu_list.value = menuNodesList.filter((item) => {
    if (item.children && item.children.length > 0) {
      return;
    }
    let lower_newKeyWords = newKeyWords.toLowerCase();
    let lower_name = item.label.toLowerCase();
    let lower_nickName = item.nickName?.toLowerCase();
    let fullName = lower_name + lower_nickName;
    return (
      PinYinMatch.match(fullName, lower_newKeyWords) ||
      fullName.includes(lower_newKeyWords)
    );
  });
  menuInitOK.value = false;
  await nextTick();
  menuInitOK.value = true;
};
/**
 * 初始化菜单列表（组装index,删除空children）
 *
 * @param menu_list 菜单列表
 * @param parent_index 父级菜单的索引，默认为空字符串
 * @returns 初始化后的菜单列表
 */
function init_menu_list(menu_list: menu[], parent_index = "") {
  let new_menu_list: menu[] = [];
  menu_list.forEach((item, index) => {
    if (!item.menuHide) {
      if (parent_index) {
        item.index = parent_index + "-" + (index + 1);
      } else {
        item.index = index + 1 + "";
      }
      if (item.children && item.children.length > 0) {
        const children = init_menu_list(item.children, item.index);
        item.children = children;
      } else {
        delete item.children;
      }
      new_menu_list.push(item);
    }
  });
  return new_menu_list;
}
// 获取树的深度
function getTreeDeep(arr: menu[]) {
  let depth = 0;
  while (arr.length > 0) {
    let temp: menu[] = [];
    for (let i = 0; i < arr.length; i++) {
      temp.push(arr[i]);
    }
    arr = [];
    for (let i = 0; i < temp.length; i++) {
      if (temp[i].children) {
        if (temp[i].children!.length > 0) {
          for (let j = 0; j < temp[i]!.children!.length; j++) {
            arr.push(temp[i].children![j]);
          }
        }
      }
    }
    if (arr.length >= 0) {
      depth++;
    }
  }
  return depth;
}
// 提取树的所有节点，最终树的所有节点都会存入传入的nodeList数组中
function getAllTreeNode(treeData: menu[], nodeList: menu[]) {
  treeData.forEach((item) => {
    if (item.children && item.children.length > 0) {
      nodeList.push(item);
      getAllTreeNode(item.children, nodeList);
    } else {
      nodeList.push(item);
    }
  });
}
</script>
<template>
  <div class="flex flex-col h-full">
    <div
      v-show="!collapse"
      class="flex flex-col justify-around h-100px items-center bg-white dark:bg-black w-299px"
    >
      <!-- 切换菜单展开层级 -->
      <el-pagination
        @current-change="openeds_change"
        :default-current-page="currentPage"
        background
        layout="prev, pager, next"
        :total="deep"
        :page-size="1"
      />
      <!-- 搜索菜单 -->
      <el-input
        clearable
        @input="keyWords_change"
        v-model="keyWords"
        style="width: 240px"
        placeholder="搜索菜单（支持拼音）"
      >
        <template #prefix>
          <S-icon icon="material-symbols:search" />
        </template>
      </el-input>
    </div>
    <el-scrollbar class="flex-grow! h-100px!">
      <el-menu
        v-if="menuInitOK"
        :collapse="collapse"
        class="el-menu-vertical"
        :default-openeds="openeds"
        :default-active="activeMenuIndex"
        @select="$emit('menu-select', $event)"
      >
        <!-- 有搜索时展示过滤后的菜单,无搜索时展示全部菜单 -->
        <S-subMenu
          v-for="(menu, index) in keyWords ? filtered_menu_list : new_menu_list"
          :key="index"
          :menu="menu"
          :collapse="collapse"
        />
      </el-menu>
    </el-scrollbar>
  </div>
</template>
<style scoped>
.el-menu-vertical {
  width: 80px !important;
  border-right: none;
}
/* 自定义菜单的宽高 */
.el-menu-vertical:not(.el-menu--collapse) {
  width: 300px !important;
}
/* 自定义翻页组件高亮页码的样式 */
:deep(.el-pagination.is-background .el-pager li.is-active) {
  background-color: #348fde !important;
}
</style>
